//
//  YZMyStocksService.m
//  YZMicroStock
//
//  Created by wangminhong on 16/4/11.
//  Copyright © 2016年 cqjr. All rights reserved.
//

#import "YZMyStocksService.h"
#import "YZMSavedStock.h"
#import "YZMStockInfo.h"

NSString *const sYZMyStocksChangedNotification = @"YZMyStocksChangedNotification";

@interface YZMyStocksService ()

@property (nonatomic, strong) NSMutableArray *storedStocks;
@property (nonatomic, strong) NSMutableDictionary *favorDict;
@property (nonatomic, strong) NSString *filePath;

@end

@implementation YZMyStocksService

+ (instancetype)sharedService
{
    static YZMyStocksService *sInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sInstance = [[self alloc] init];;
    });
    
    return sInstance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        NSArray *userDocs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask,  YES);
        @try {
            NSString *docPath = userDocs[0];
            self.filePath = [docPath stringByAppendingPathComponent: @"FavorStock.data"];
        }
        @catch (NSException *exception) {
            NSLog(@"%@", exception);
        }
        
        self.favorDict = [NSMutableDictionary dictionary];
        self.storedStocks = [NSMutableArray array];
        
        [self mergeFromFile];
        
        [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(noticeForResignActive:) name: UIApplicationWillResignActiveNotification object: nil];
    }
    return self;
}


#pragma mark -- operation

- (NSArray *)stocks{
    
    return [self.storedStocks mutableCopy];
}

- (void)actionForStocksChanged
{
    [[NSNotificationCenter defaultCenter] postNotificationName: sYZMyStocksChangedNotification object: nil];
}

- (BOOL)addStockWithCode:(NSString *)code andName:(NSString *)name{
    
   return [self addStockWithCode:code andName:name andAdjustFlag:NO];
}

- (BOOL)addStockWithCode:(NSString *)code andName:(NSString *)name andAdjustFlag:(BOOL)adjustFlag{
    
    if (!adjustFlag && self.storedStocks.count >= 20) {
        
        [MBProgressHUD showMessage:@"已达到20条最大保存记录数"];
        return NO;
    }
    
    if(code.length == 0) {
        return NO;
    }
    @synchronized(self)
    {
        YZMSavedStock *favorStock = self.favorDict[code];
        if (favorStock == nil) {
            favorStock = [[YZMSavedStock alloc] init];
            [self.storedStocks insertObject:favorStock atIndex:0];
            [self.favorDict setObject:favorStock forKey:code];
        }
        else
        {
            [self.storedStocks removeObject: favorStock];
            [self.storedStocks insertObject: favorStock atIndex: 0];
        }
        
        favorStock.code = code;
        if (name.length > 0) {
            
            favorStock.name = name;
        }
    }
    
    [self save];
    [self actionForStocksChanged];
    return YES;
}

- (BOOL)isStockExist: (NSString *)stockID
{
    YZMSavedStock *favorStock = self.favorDict[stockID];
    return (favorStock!=nil);
}

- (BOOL)operationStock:(YZMStockInfo *)stock withAddFlag:(BOOL)addFlag{
    if (addFlag) {
        
       return [self addStock:stock];
    }else{
       return [self removeStock:stock];
    }
}

- (BOOL)addStock:(YZMStockInfo *)stock{
    
   return [self addStockWithCode:stock.code andName:stock.name];
}
- (BOOL)removeStock:(YZMStockInfo *)stock{
    
   return [self removeStockWithCode:stock.code];
}

- (BOOL)topStockWithCode:(NSString *)code{
    
   return [self addStockWithCode:code andName:nil andAdjustFlag:YES];
}

- (void)exchangeStockAtIndex:(NSInteger)atIndex toIndex:(NSInteger)toIndex{
    
    if (self.storedStocks.count <= atIndex || self.storedStocks.count <= toIndex) {
        
        return;
    }
    
    YZMSavedStock *stock = self.storedStocks[atIndex];
    @synchronized(self)
    {
        [self.storedStocks removeObject:stock];
        [self.storedStocks insertObject:stock atIndex:toIndex];
    }
    
    [self save];
    [self actionForStocksChanged];
}

- (void)removeSavedStocksWithCodeList:(NSSet *)codeList{
    
    NSArray *codeListArray = [codeList allObjects];
    NSArray *favorStocks = [self.favorDict objectsForKeys:codeListArray notFoundMarker:[NSNull class]];
    if (favorStocks.count == 0) {
        
        return;
    }
    
    @synchronized(self)
    {
        [self.favorDict removeObjectsForKeys:codeListArray];
        [self.storedStocks removeObjectsInArray:favorStocks];
    }
    
    [self save];
    [self actionForStocksChanged];
}

- (BOOL)removeStockWithCode:(NSString *)code{
    
    if (code.length == 0) {
        return NO;
    }
    YZMSavedStock *favorStock = self.favorDict[code];
    if (favorStock) {
        @synchronized(self)
        {
            [self.favorDict removeObjectForKey:code];
            [self.storedStocks removeObject: favorStock];
        }
    }
    
    [self save];
    [self actionForStocksChanged];
    return YES;
}

#pragma mark -- private method

- (void)noticeForResignActive:(id)notice{
    
    [self save];
}

- (void)save
{
    [NSKeyedArchiver archiveRootObject: self.storedStocks toFile: self.filePath];
}

- (void)_unsafeMergeFromItems: (NSArray *)items
{
    for (YZMSavedStock *item in items) {
        if (item.code.length == 0 || self.favorDict[item.code]) {
            continue;
        }
        [self.favorDict setObject: item forKey: item.code];
        [self.storedStocks addObject: item];
    }
}

- (void)mergeFromItems: (NSArray *)items
{
    [self mergeFromItems: items silent: NO];
}

- (void)mergeFromItems: (NSArray *)items silent: (BOOL)silent
{
    
    @synchronized(self)
    {
        [self _unsafeMergeFromItems: items];
    }
    if (self.storedStocks.count > 0 && !silent) {
        [self actionForStocksChanged];
    }
}

- (void)mergeFromFile
{
    NSArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithFile: self.filePath];
    [self mergeFromItems: tempArray silent: YES];
}

@end
